package main

import (
	"database/sql"
	"fmt"
	"os"
	"path"
	"strconv"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	if len(os.Args) != 3 {
		fmt.Println("usage: ")
		fmt.Println("    fix-cellno.exe cell ./cell.db")
		fmt.Println("    fix-cellno.exe slide ./slide.db")
		os.Exit(0)
	}

	dbtype := os.Args[1]
	dbpath := os.Args[2]

	if dbtype == "slide" {
		upadte(dbpath)
	}

	if dbtype == "cell" {

		fi, err := os.Stat("files")
		if err != nil {
			fmt.Println("没有找到 files 文件夹")
			os.Exit(0)
		}
		if !fi.IsDir() {
			fmt.Println("没有找到 files 文件夹")
			os.Exit(0)
		}

		db, err := sql.Open("sqlite3", dbpath)
		checkErr(err)

		defer db.Close()

		rows, err := db.Query("SELECT slide_no FROM slides")
		checkErr(err)

		var nos []string

		for rows.Next() {
			var slide_no string
			err = rows.Scan(&slide_no)
			checkErr(err)
			fmt.Println(slide_no)
			nos = append(nos, slide_no)
		}

		for _, slide_no := range nos {
			upadte(path.Join("./files", slide_no, "slide.db"))
		}
	}
}

func upadte(slide_path string) {
	db, err := sql.Open("sqlite3", slide_path)
	checkErr(err)

	defer db.Close()

	rows, err := db.Query("select id from cells where level = 0")
	checkErr(err)

	i := 1
	tx, err := db.Begin()

	tx.Exec(fmt.Sprintf("update cells set cell_no = '0'"))

	checkErr(err)

	for rows.Next() {

		var id string
		err = rows.Scan(&id)
		checkErr(err)

		_, err := tx.Exec(fmt.Sprintf("update cells set cell_no = '%d' where id = '%s'", i, id))
		checkErr(err)

		i += 1
	}
	tx.Commit()

	upadteLevel(slide_path, 1)
	upadteLevel(slide_path, 2)
	upadteLevel(slide_path, 3)
}

func upadteLevel(slide_path string, level int) {
	if level == 0 {
		return
	}
	db, err := sql.Open("sqlite3", slide_path)
	checkErr(err)

	defer db.Close()

	rows, err := db.Query("select id, cell_no, level from cells")

	i := 0

	tx, err := db.Begin()
	checkErr(err)

	for rows.Next() {
		var id string
		var cell_no string
		var _level int
		err = rows.Scan(&id, &cell_no, &_level)
		checkErr(err)

		if _level >= level {
			continue
		}

		fmt.Println(id, cell_no)

		_, err := tx.Exec(fmt.Sprintf("update cells set cell_no = '%s' where p_id = '%s'", cell_no, id))
		checkErr(err)

		ii, err := strconv.Atoi(cell_no)
		checkErr(err)

		if i < ii {
			i = ii
		}
	}

	tx.Commit()

	tx, err = db.Begin()
	checkErr(err)

	rows, err = tx.Query(fmt.Sprintf("select id from cells where level = %d", level))

	for rows.Next() {
		i += 1
		var id string
		err = rows.Scan(&id)
		checkErr(err)

		_, err := tx.Exec(fmt.Sprintf("update cells set cell_no = '%d' where id = '%s'", i, id))
		checkErr(err)
	}

	tx.Commit()
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}
